<?xml version="1.0" encoding="UTF-8" ?>
<!--

    Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
    under one or more contributor license agreements. See the NOTICE file
    distributed with this work for additional information regarding copyright
    ownership. Camunda licenses this file to you under the Apache License,
    Version 2.0; you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="org.camunda.bpm.engine.impl.history.event.HistoricDecisionInstanceEntity">

  <resultMap id="finishedReportResultMap" type="org.camunda.bpm.engine.impl.persistence.entity.CleanableHistoricDecisionInstanceReportResultEntity">
    <result property="cleanableDecisionInstanceCount" column="CLEANABLE_" jdbcType="BIGINT" />
    <result property="finishedDecisionInstanceCount" column="FINISHED_" jdbcType="BIGINT" />
    <result property="decisionDefinitionId" column="ID_" jdbcType="VARCHAR" />
    <result property="decisionDefinitionKey" column="KEY_" jdbcType="VARCHAR" />
    <result property="decisionDefinitionName" column="NAME_" jdbcType="VARCHAR" />
    <result property="decisionDefinitionVersion" column="VERSION_" jdbcType="VARCHAR" />
    <result property="historyTimeToLive" column="HISTORY_TTL_" jdbcType="BIGINT" />
    <result property="tenantId" column="TENANT_ID_" jdbcType="VARCHAR"/>
  </resultMap>

 <!-- insert -->

 <insert id="insertHistoricDecisionInstance" parameterType="org.camunda.bpm.engine.impl.history.event.HistoricDecisionInstanceEntity">
    insert into ${prefix}ACT_HI_DECINST(
      ID_,
      DEC_DEF_ID_,
      DEC_DEF_KEY_,
      DEC_DEF_NAME_,
      PROC_DEF_KEY_,
      PROC_DEF_ID_,
      PROC_INST_ID_,
      CASE_DEF_KEY_,
      CASE_DEF_ID_,
      CASE_INST_ID_,
      ACT_INST_ID_,
      ACT_ID_,
      EVAL_TIME_,
      REMOVAL_TIME_,
      COLLECT_VALUE_,
      USER_ID_,
      ROOT_DEC_INST_ID_,
      ROOT_PROC_INST_ID_,
      DEC_REQ_ID_,
      DEC_REQ_KEY_,
      TENANT_ID_)
    values (#{id, jdbcType=VARCHAR},
            #{decisionDefinitionId, jdbcType=VARCHAR},
            #{decisionDefinitionKey, jdbcType=VARCHAR},
            #{decisionDefinitionName, jdbcType=VARCHAR},
            #{processDefinitionKey, jdbcType=VARCHAR},
            #{processDefinitionId, jdbcType=VARCHAR},
            #{processInstanceId, jdbcType=VARCHAR},
            #{caseDefinitionKey, jdbcType=VARCHAR},
            #{caseDefinitionId, jdbcType=VARCHAR},
            #{caseInstanceId, jdbcType=VARCHAR},
            #{activityInstanceId, jdbcType=VARCHAR},
            #{activityId, jdbcType=VARCHAR},
            #{evaluationTime, jdbcType=TIMESTAMP},
            #{removalTime, jdbcType=TIMESTAMP},
            #{collectResultValue, jdbcType=DOUBLE},
            #{userId, jdbcType=VARCHAR},
            #{rootDecisionInstanceId, jdbcType=VARCHAR},
            #{rootProcessInstanceId, jdbcType=VARCHAR},
            #{decisionRequirementsDefinitionId, jdbcType=VARCHAR},
            #{decisionRequirementsDefinitionKey, jdbcType=VARCHAR},
            #{tenantId, jdbcType=VARCHAR}
           )
  </insert>
  
  <!-- update -->

  <update id="updateHistoricDecisionInstancesByRootProcessInstanceId"
          parameterType="java.util.Map">
      update ${prefix}ACT_HI_DECINST set
      REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}

      where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR}
  </update>

  <update id="updateHistoricDecisionInstancesByRootProcessInstanceId_mssql"
          parameterType="java.util.Map">
    update RES set
    RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}
    FROM ${prefix}ACT_HI_DECINST RES WITH (FORCESEEK)
    where RES.ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR}
  </update>

  <update id="updateHistoricDecisionInstancesByProcessInstanceId"
          parameterType="java.util.Map">
    update ${prefix}ACT_HI_DECINST
      set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}
      where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR}
  </update>

  <update id="updateHistoricDecisionInstancesByProcessInstanceId_mssql"
          parameterType="java.util.Map">
    update RES
    set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}
    FROM ${prefix}ACT_HI_DECINST RES WITH (FORCESEEK)
    where RES.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR}
  </update>

  <update id="updateHistoricDecisionInstancesByRootDecisionInstanceId"
          parameterType="java.util.Map">
      update ${prefix}ACT_HI_DECINST set
      REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}

      where ROOT_DEC_INST_ID_ = #{rootDecisionInstanceId, jdbcType=VARCHAR} <!-- null for root dec instances -->
         or ID_ = #{rootDecisionInstanceId, jdbcType=VARCHAR}
  </update>

  <update id="updateHistoricDecisionInstancesByRootDecisionInstanceId_mssql"
          parameterType="java.util.Map">
    update RES set
    RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}
    FROM ${prefix}ACT_HI_DECINST RES WITH (FORCESEEK)
    where RES.ROOT_DEC_INST_ID_ = #{rootDecisionInstanceId, jdbcType=VARCHAR} <!-- null for root dec instances -->
    or RES.ID_ = #{rootDecisionInstanceId, jdbcType=VARCHAR}
  </update>

  <update id="updateHistoricDecisionInstancesByDecisionInstanceId"
          parameterType="java.util.Map">
      update ${prefix}ACT_HI_DECINST set
      REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}

      where ID_ = #{decisionInstanceId, jdbcType=VARCHAR}
  </update>

  <update id="updateHistoricDecisionInstancesByDecisionInstanceId_mssql"
          parameterType="java.util.Map">
    update RES set
    RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}
    FROM ${prefix}ACT_HI_DECINST RES WITH (FORCESEEK)
    where RES.ID_ = #{decisionInstanceId, jdbcType=VARCHAR}
  </update>

  <!-- delete -->

  <delete id="deleteHistoricDecisionInstance" parameterType="org.camunda.bpm.engine.impl.history.event.HistoricDecisionInstanceEntity">
    delete from ${prefix}ACT_HI_DECINST where ID_ = #{id}
  </delete>

  <delete id="deleteHistoricDecisionInstanceByIds">
    delete
    from ${prefix}ACT_HI_DECINST
    where
      <bind name="listOfIds" value="list"/>
      <bind name="fieldName" value="'ID_'"/>
      <include refid="org.camunda.bpm.engine.impl.persistence.entity.Commons.applyInForPaginatedCollection"/>
  </delete>

  <delete id="deleteHistoricDecisionInstancesByRemovalTime"
          parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject">
    <bind name="date" value="'REMOVAL_TIME_'"/>
    <bind name="reportPeriodUnitName" value="'MINUTE'"/>
    delete ${limitBeforeWithoutOffset} from ${prefix}ACT_HI_DECINST
    where REMOVAL_TIME_ &lt;= #{parameter.removalTime}
    <include refid="andWhereMinuteInDateBetweenSql"/>
    ${limitAfterWithoutOffset}
  </delete>

  <delete id="deleteHistoricDecisionInstancesByRemovalTime_oracle"
          parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject">
    <bind name="date" value="'REMOVAL_TIME_'"/>
    <bind name="reportPeriodUnitName" value="'MINUTE'"/>
    delete ${limitBeforeWithoutOffset} from ${prefix}ACT_HI_DECINST
    where REMOVAL_TIME_ &lt;= #{parameter.removalTime}
    <include refid="andWhereMinuteInDateBetweenSql_oracle"/>
    ${limitAfterWithoutOffset}
  </delete>

  <delete id="deleteHistoricDecisionInstancesByRemovalTime_postgres_or_db2"
          parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject">
    <bind name="date" value="'REMOVAL_TIME_'"/>
    <bind name="reportPeriodUnitName" value="'MINUTE'"/>
    delete ${limitBeforeWithoutOffset} from ${prefix}ACT_HI_DECINST
    where ID_ IN
      (SELECT ID_
       FROM ${prefix}ACT_HI_DECINST
       WHERE REMOVAL_TIME_ &lt;= #{parameter.removalTime} <include refid="andWhereMinuteInDateBetweenSql"/>
       ${limitAfterWithoutOffset})
  </delete>

  <!-- result map -->

 <resultMap id="historicDecisionInstanceResultMap" type="org.camunda.bpm.engine.impl.history.event.HistoricDecisionInstanceEntity">
    <id property="id" column="ID_" jdbcType="VARCHAR" />
    <result property="decisionDefinitionId" column="DEC_DEF_ID_" jdbcType="VARCHAR" />
    <result property="decisionDefinitionKey" column="DEC_DEF_KEY_" jdbcType="VARCHAR" />
    <result property="decisionDefinitionName" column="DEC_DEF_NAME_" jdbcType="VARCHAR" />
    <result property="processDefinitionKey" column="PROC_DEF_KEY_" jdbcType="VARCHAR" />
    <result property="processDefinitionId" column="PROC_DEF_ID_" jdbcType="VARCHAR"/>
    <result property="processInstanceId" column="PROC_INST_ID_" jdbcType="VARCHAR"/>
    <result property="caseDefinitionKey" column="CASE_DEF_KEY_" jdbcType="VARCHAR" />
    <result property="caseDefinitionId" column="CASE_DEF_ID_" jdbcType="VARCHAR"/>
    <result property="caseInstanceId" column="CASE_INST_ID_" jdbcType="VARCHAR"/>
    <result property="activityInstanceId" column="ACT_INST_ID_" jdbcType="VARCHAR"/>
    <result property="activityId" column="ACT_ID_" jdbcType="VARCHAR"/>
    <result property="evaluationTime" column="EVAL_TIME_" jdbcType="TIMESTAMP"/>
    <result property="removalTime" column="REMOVAL_TIME_" jdbcType="TIMESTAMP"/>
    <result property="collectResultValue" column="COLLECT_VALUE_" jdbcType="DOUBLE"/>
    <result property="userId" column="USER_ID_" jdbcType="VARCHAR"/>
    <result property="rootDecisionInstanceId" column="ROOT_DEC_INST_ID_" jdbcType="VARCHAR"/>
    <result property="rootProcessInstanceId" column="ROOT_PROC_INST_ID_" jdbcType="VARCHAR"/>
    <result property="decisionRequirementsDefinitionId" column="DEC_REQ_ID_" jdbcType="VARCHAR"/>
    <result property="decisionRequirementsDefinitionKey" column="DEC_REQ_KEY_" jdbcType="VARCHAR"/>
    <result property="tenantId" column="TENANT_ID_" jdbcType="VARCHAR"/>
  </resultMap>

  <resultMap type="org.camunda.bpm.engine.impl.util.ImmutablePair" id="deploymentIdMapping">
    <id property="left" column="DEPLOYMENT_ID_" jdbcType="VARCHAR" />
    <id property="right" column="ID_" jdbcType="VARCHAR" />
  </resultMap>

  <!-- select -->

  <select id="selectHistoricDecisionInstancesByDecisionDefinitionId" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject" resultMap="historicDecisionInstanceResultMap">
    select * from ${prefix}ACT_HI_DECINST RES
    where DEC_DEF_ID_ = #{parameter, jdbcType=VARCHAR}
    <include refid="org.camunda.bpm.engine.impl.persistence.entity.TenantEntity.queryTenantCheck" />
  </select>

  <select id="selectHistoricDecisionInstanceByDecisionInstanceId" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject" resultMap="historicDecisionInstanceResultMap">
    select * from ${prefix}ACT_HI_DECINST RES
    where ID_ = #{parameter, jdbcType=VARCHAR}
  </select>

  <select id="selectHistoricDecisionInstancesByQueryCriteria" parameterType="org.camunda.bpm.engine.impl.HistoricDecisionInstanceQueryImpl" resultMap="historicDecisionInstanceResultMap">
    <include refid="org.camunda.bpm.engine.impl.persistence.entity.Commons.bindOrderBy"/>
    ${limitBefore}
    select ${distinct} RES.*
    ${limitBetween}
    <include refid="selectHistoricDecisionInstancesByQueryCriteriaSql"/>
    ${orderBy}
    ${limitAfter}
  </select>

  <select id="selectHistoricDecisionInstanceCountByQueryCriteria" parameterType="org.camunda.bpm.engine.impl.HistoricDecisionInstanceQueryImpl" resultType="long">
    ${countDistinctBeforeStart} RES.ID_ ${countDistinctBeforeEnd}
    <include refid="selectHistoricDecisionInstancesByQueryCriteriaSql"/>
    ${countDistinctAfterEnd}
  </select>

  <select id="selectHistoricDecisionInstanceDeploymentIdMappingsByQueryCriteria" parameterType="org.camunda.bpm.engine.impl.HistoricDecisionInstanceQueryImpl" resultMap="deploymentIdMapping">
    select distinct DD.DEPLOYMENT_ID_, RES.ID_
    <include refid="selectHistoricDecisionInstancesByQueryCriteriaSql"/>
    left join ${prefix}ACT_RE_DECISION_DEF DD on RES.DEC_DEF_ID_ = DD.ID_
    order by DD.DEPLOYMENT_ID_ ASC
  </select>

  <!-- native queries -->
  
  <select id="selectHistoricDecisionInstancesByNativeQuery" parameterType="java.util.Map" resultMap="historicDecisionInstanceResultMap">
    <if test="resultType == 'LIST_PAGE'">
      ${limitBefore}
    </if>
    ${sql}
    <if test="resultType == 'LIST_PAGE'">
      ${limitAfter}
    </if>
  </select>

  <select id="selectHistoricDecisionInstanceCountByNativeQuery" parameterType="java.util.Map" resultType="long">
    ${sql}
  </select>
  
  <!-- special nativ query for mssql and db2 -->
  
  <select id="selectHistoricDecisionInstancesByNativeQuery_mssql_or_db2" parameterType="java.util.Map" resultMap="historicDecisionInstanceResultMap">
    <if test="resultType == 'LIST_PAGE'">
        ${limitBeforeNativeQuery}
    </if>
    ${sql}
    <if test="resultType == 'LIST_PAGE'">
      ${limitAfter}
    </if>
  </select>
  
   <!-- sql query -->

  <sql id="selectHistoricDecisionInstancesByQueryCriteriaSql">
    from (
    select RES.*
    from ${prefix}ACT_HI_DECINST RES

    <if
        test="authCheck.shouldPerformAuthorizatioCheck &amp;&amp; !authCheck.revokeAuthorizationCheckEnabled &amp;&amp; authCheck.authUserId != null">
      <include
          refid="org.camunda.bpm.engine.impl.persistence.entity.AuthorizationEntity.authCheckJoinWithoutOnClause"/>
      AUTH ON (AUTH.RESOURCE_ID_ ${authJoinStart} RES.DEC_DEF_KEY_ ${authJoinSeparator} '*' ${authJoinEnd})
    </if>

    <where>
      <if test="decisionInstanceId != null">
        RES.ID_ = #{decisionInstanceId}
      </if>
      <if test="decisionInstanceIdIn != null and decisionInstanceIdIn.length > 0">
        <bind name="listOfIds" value="decisionInstanceIdIn" />
        <bind name="fieldName" value="'RES.ID_'" />
        <include refid="org.camunda.bpm.engine.impl.persistence.entity.Commons.applyInForPaginatedArray" />
      </if>
      <if test="decisionDefinitionId != null">
        and RES.DEC_DEF_ID_ = #{decisionDefinitionId}
      </if>
      <if test="decisionDefinitionIdIn != null and decisionDefinitionIdIn.length > 0">
        and RES.DEC_DEF_ID_ in
        <foreach item="item" index="index" collection="decisionDefinitionIdIn" open="("
                 separator="," close=")">
          #{item}
        </foreach>
      </if>
      <if test="decisionDefinitionKey != null">
        and RES.DEC_DEF_KEY_ = #{decisionDefinitionKey}
      </if>
      <if test="decisionDefinitionKeyIn != null and decisionDefinitionKeyIn.length > 0">
        and RES.DEC_DEF_KEY_ in
        <foreach item="item" index="index" collection="decisionDefinitionKeyIn" open="("
                 separator="," close=")">
          #{item}
        </foreach>
      </if>
      <if test="decisionDefinitionName != null">
        and RES.DEC_DEF_NAME_ = #{decisionDefinitionName}
      </if>
      <if test="decisionDefinitionNameLike != null">
        and RES.DEC_DEF_NAME_ like #{decisionDefinitionNameLike} ESCAPE ${escapeChar}
      </if>
      <if test="processDefinitionKey != null">
        and RES.PROC_DEF_KEY_ = #{processDefinitionKey}
      </if>
      <if test="processDefinitionId != null">
        and RES.PROC_DEF_ID_ = #{processDefinitionId}
      </if>
      <if test="processInstanceId != null">
        and RES.PROC_INST_ID_ = #{processInstanceId}
      </if>
      <if test="caseDefinitionKey != null">
        and RES.CASE_DEF_KEY_ = #{caseDefinitionKey}
      </if>
      <if test="caseDefinitionId != null">
        and RES.CASE_DEF_ID_ = #{caseDefinitionId}
      </if>
      <if test="caseInstanceId != null">
        and RES.CASE_INST_ID_ = #{caseInstanceId}
      </if>

      <if test="activityInstanceIds != null &amp;&amp; activityInstanceIds.length > 0">
        and RES.ACT_INST_ID_ in
        <foreach item="activityInstanceId" index="index" collection="activityInstanceIds"
                 open="(" separator="," close=")">
          #{activityInstanceId}
        </foreach>
      </if>

      <if test="activityIds != null &amp;&amp; activityIds.length > 0">
        and RES.ACT_ID_ in
        <foreach item="activityId" index="index" collection="activityIds" open="(" separator=","
                 close=")">
          #{activityId}
        </foreach>
      </if>

      <if test="evaluatedBefore != null">
        and RES.EVAL_TIME_ &lt;= #{evaluatedBefore}
      </if>
      <if test="evaluatedAfter != null">
        and RES.EVAL_TIME_ &gt;= #{evaluatedAfter}
      </if>

      <if test="userId != null">
        and RES.USER_ID_ = #{userId}
      </if>

      <if test="rootDecisionInstanceId != null">
        and (RES.ROOT_DEC_INST_ID_ = #{rootDecisionInstanceId} or
          (RES.ROOT_DEC_INST_ID_ is null and RES.ID_ = #{rootDecisionInstanceId}))
      </if>

      <if test="rootDecisionInstancesOnly">
        and RES.ROOT_DEC_INST_ID_ is null
      </if>

      <if test="decisionRequirementsDefinitionId != null">
        and RES.DEC_REQ_ID_ = #{decisionRequirementsDefinitionId}
      </if>

      <if test="decisionRequirementsDefinitionKey != null">
        and RES.DEC_REQ_KEY_ = #{decisionRequirementsDefinitionKey}
      </if>

      <if test="isTenantIdSet">
        <if test="tenantIds != null &amp;&amp; tenantIds.length > 0">
          and RES.TENANT_ID_ in
          <foreach item="tenantId" index="index" collection="tenantIds"
                   open="(" separator="," close=")">
            #{tenantId}
          </foreach>
        </if>
        <if test="tenantIds == null">
          and RES.TENANT_ID_ is null
        </if>
      </if>

      <if test="authCheck.shouldPerformAuthorizatioCheck &amp;&amp; authCheck.authUserId != null">
        and (
          (RES.DEC_DEF_KEY_ is not null
          <include
              refid="org.camunda.bpm.engine.impl.persistence.entity.AuthorizationEntity.queryAuthorizationCheck"/>
          ) or RES.DEC_DEF_KEY_ is null
        )
      </if>

      <include
          refid="org.camunda.bpm.engine.impl.persistence.entity.TenantEntity.queryTenantCheck" />

    </where>
    ) RES
  </sql>

  <!-- Select ids for async history cleanup -->
  <sql id="selectHistoricDecisionInstanceIdsForCleanupSql">
    <bind name="days" value="'dd.HISTORY_TTL_'"/>
    <bind name="date" value="'di.EVAL_TIME_'"/>
    <bind name="currentTimestamp" value="parameter.currentTimestamp"/>
    <bind name="reportPeriodUnitName" value="'MINUTE'"/>
    FROM ${prefix}ACT_HI_DECINST di, ${prefix}ACT_RE_DECISION_DEF dd
    where
        di.DEC_DEF_ID_ = dd.ID_
        AND not dd.HISTORY_TTL_ is NULL
        AND ${dayComparator}
  </sql>

  <select id="selectHistoricDecisionInstanceIdsForCleanup" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject" resultType="string">
    SELECT ${limitBeforeWithoutOffset} di.ID_, di.EVAL_TIME_
    <include refid="selectHistoricDecisionInstanceIdsForCleanupSql"/>
    <include refid="andWhereMinuteInDateBetweenSql"/>
    ${limitAfterWithoutOffset}
  </select>

  <select id="selectHistoricDecisionInstanceIdsForCleanup_oracle" parameterType="org.camunda.bpm.engine.impl.db.ListQueryParameterObject" resultType="string">
    SELECT /*+ FIRST_ROWS(${maxResults}) NO_PARALLEL(di) NO_PARALLEL(dd) */ di.ID_, di.EVAL_TIME_
    <include refid="selectHistoricDecisionInstanceIdsForCleanupSql"/>
    <include refid="andWhereMinuteInDateBetweenSql_oracle"/>
    ${limitAfterWithoutOffset}
  </select>

  <sql id="andWhereMinuteInDateBetweenSql">
    <if test="parameter.minuteFrom != null and parameter.minuteTo != null">
      AND ${datepart1}<include refid="org.camunda.bpm.engine.impl.persistence.entity.Commons.periodUnitFunction"/>${datepart2}${date}${datepart3}
      between #{parameter.minuteFrom, jdbcType=INTEGER} and #{parameter.minuteTo, jdbcType=INTEGER}
    </if>
  </sql>

  <sql id="andWhereMinuteInDateBetweenSql_oracle">
    <if test="parameter.minuteFrom != null and parameter.minuteTo != null">
      AND ${datepart1}${date}${datepart2}<include refid="org.camunda.bpm.engine.impl.persistence.entity.Commons.periodUnitFunction"/>${datepart3}
      between #{parameter.minuteFrom, jdbcType=INTEGER} and #{parameter.minuteTo, jdbcType=INTEGER}
    </if>
  </sql>

  <!-- Select History Cleanup Report Entities -->
  <select id="selectFinishedDecisionInstancesReportEntitiesCount" parameterType="org.camunda.bpm.engine.impl.CleanableHistoricDecisionInstanceReportImpl" resultType="long">
    ${countDistinctBeforeStart} RES.ID_ ${countDistinctBeforeEnd}
    <include refid="selectFinishedDecisionInstancesReportEntitiesSql" />
    ${countDistinctAfterEnd}
  </select>

  <select id="selectFinishedDecisionInstancesReportEntities" parameterType="org.camunda.bpm.engine.impl.CleanableHistoricProcessInstanceReportImpl" resultMap="finishedReportResultMap">
    <include refid="org.camunda.bpm.engine.impl.persistence.entity.Commons.bindOrderBy"/>
    ${limitBefore}
    SELECT ${distinct} RES.*
    ${limitBetween}
    <include refid="selectFinishedDecisionInstancesReportEntitiesSql" />
    ${orderBy}
    ${limitAfter}
  </select>

  <sql id="selectFinishedDecisionInstancesReportEntitiesSql">
    <bind name="days" value="'RES.HISTORY_TTL_'"/>
    <bind name="date" value="'DI.EVAL_TIME_'"/>

    FROM (
      SELECT RES.ID_,
        RES.KEY_,
        RES.NAME_,
        RES.VERSION_,
        RES.HISTORY_TTL_,
        RES.TENANT_ID_,
        F.FINISHED_,
        <choose>
          <when test="isHistoryCleanupStrategyRemovalTimeBased">
            SUM(CASE WHEN DI.REMOVAL_TIME_ is not null and DI.REMOVAL_TIME_ &lt;= #{currentTimestamp} THEN 1 ELSE 0 END) AS CLEANABLE_
          </when>
          <otherwise>
            SUM(CASE WHEN RES.HISTORY_TTL_ is not null and DI.EVAL_TIME_ is not null and (RES.HISTORY_TTL_=0 OR ${dayComparator}) THEN 1 ELSE 0 END) AS CLEANABLE_
          </otherwise>
        </choose>
      FROM
        (
          SELECT DISTINCT RES.*
          FROM ${prefix}ACT_RE_DECISION_DEF RES
          <if test="authCheck.shouldPerformAuthorizatioCheck &amp;&amp; !authCheck.revokeAuthorizationCheckEnabled &amp;&amp; authCheck.authUserId != null">
            <include refid="org.camunda.bpm.engine.impl.persistence.entity.AuthorizationEntity.authCheckJoinWithoutOnClause" />
            AUTH ON (AUTH.RESOURCE_ID_ ${authJoinStart} RES.KEY_ ${authJoinSeparator} '*' ${authJoinEnd})
          </if>
          <where>

            <if test="decisionDefinitionIdIn != null &amp;&amp; decisionDefinitionIdIn.length > 0">
              RES.ID_ IN
              <foreach item="decisionInstanceId" index="index" collection="decisionDefinitionIdIn" open="(" separator="," close=")">
                  #{decisionInstanceId}
              </foreach>
            </if>

            <if test="decisionDefinitionKeyIn != null &amp;&amp; decisionDefinitionKeyIn.length > 0">
              and RES.KEY_ IN
              <foreach item="decisionInstanceKey" index="index" collection="decisionDefinitionKeyIn" open="(" separator="," close=")">
                  #{decisionInstanceKey}
              </foreach>
            </if>

            <if test="isTenantIdSet">
              <if test="tenantIdIn != null &amp;&amp; tenantIdIn.length > 0">
                and RES.TENANT_ID_ in
                <foreach item="tenantId" index="index" collection="tenantIdIn"
                         open="(" separator="," close=")">
                  #{tenantId}
                </foreach>
              </if>
              <if test="tenantIdIn == null">
                and RES.TENANT_ID_ is null
              </if>
            </if>

            <include refid="org.camunda.bpm.engine.impl.persistence.entity.AuthorizationEntity.queryAuthorizationCheck" />
            <include refid="org.camunda.bpm.engine.impl.persistence.entity.TenantEntity.queryTenantCheck" />

          </where>
        ) RES
        LEFT JOIN ${prefix}ACT_HI_DECINST DI
        ON DI.DEC_DEF_ID_ = RES.ID_
        LEFT JOIN (
          SELECT COUNT(DI.ID_) AS FINISHED_
              ,DI.DEC_DEF_ID_
          FROM ${prefix}ACT_HI_DECINST DI
          WHERE DI.EVAL_TIME_ IS NOT NULL
          GROUP BY DI.DEC_DEF_ID_
          ) F ON F.DEC_DEF_ID_ = DI.DEC_DEF_ID_

        <if test="isCompact">
          WHERE FINISHED_ > 0
        </if>

        GROUP BY RES.ID_,
          RES.KEY_,
          RES.NAME_,
          RES.VERSION_,
          RES.HISTORY_TTL_,
          RES.TENANT_ID_,
          F.FINISHED_

    ) RES

  </sql>

  <select id="selectHistoricDecisionInstancePage" resultMap="historicDecisionInstanceResultMap"
          parameterType="java.util.Map">
    <bind name="maxResults" value="parameter.maxResults"/>

    ${optimizeLimitBeforeWithoutOffset}
    select ${limitBeforeWithoutOffset} * from ${prefix}ACT_HI_DECINST RES

    <where>
      <if test="parameter.evaluatedAfter != null">
        and RES.EVAL_TIME_ &gt; #{parameter.evaluatedAfter}
      </if>
      <if test="test=parameter.evaluatedAt != null">
        and RES.EVAL_TIME_ = #{parameter.evaluatedAt}
      </if>
    </where>

    ORDER BY RES.EVAL_TIME_ ASC
    ${optimizeLimitAfterWithoutOffset}

  </select>

</mapper>
